package com.guchenbo.example.dubbo.rpc.manual;

import com.guchenbo.example.dubbo.template.InvokerTemplate;
import java.lang.reflect.Method;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.AsyncRpcResult;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;

public class WorkerInvoker<T> extends InvokerTemplate<T> {

  private Object proxy;

  public WorkerInvoker(Class<T> type, URL url, Object proxy) {
    super(type, url);
    this.proxy = proxy;
  }

  /**
   * Result AppResponse
   *
   * @param invocation
   * @return
   * @throws RpcException
   */
  @Override
  protected Result doInvoke(Invocation invocation) throws RpcException {
    AsyncRpcResult result;
    try {
      Object object = invokeLocal(invocation);
      result = AsyncRpcResult.newDefaultAsyncResult(object, null, invocation);
    } catch (Exception e) {
      result = AsyncRpcResult.newDefaultAsyncResult(null, e, invocation);
    }
    return result;
  }

  private Object invokeLocal(Invocation invocation) throws Exception {
    Method method = getInterface()
        .getMethod(invocation.getMethodName(), invocation.getParameterTypes());
    return method.invoke(proxy, invocation.getArguments());
  }
}
